package org.quickjsf.core.datamodel;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.quickjsf.core.base.viewmodel.vo.FieldFilter;
import org.quickjsf.core.base.viewmodel.vo.FieldFilter.CondType;

public class HibernateFieldFilter {
	
	public static void setFilter(Criteria criteria, List<FieldFilter> fieldFilters) {
	    if (null != fieldFilters) {
	    	for (FieldFilter fieldFilter : fieldFilters) {
	    		switch (fieldFilter.getCondition()) {
				case CondType.ALL_COND:
					try {
							searchAll(criteria, fieldFilter);
						} catch (Exception e) {
							e.printStackTrace();
						}
					break;
				case CondType.EQ:
					criteria.add(Restrictions.eq(fieldFilter.getField(), fieldFilter.getValue()));
					break;
				case CondType.LE:
					criteria.add(Restrictions.le(fieldFilter.getField(), fieldFilter.getValue()));
					break;
				case CondType.GT:
					criteria.add(Restrictions.gt(fieldFilter.getField(), fieldFilter.getValue()));
					break;	
				case CondType.BETWEEN:
					criteria.add(Restrictions.between(fieldFilter.getField(), fieldFilter.getValue(), fieldFilter.getOtherValue()));
					break;
				case CondType.LIKE:
					criteria.add(Restrictions.like(fieldFilter.getField(), "%"+fieldFilter.getValue()+"%"));
					break;
				default:
					break;
				}
	    	}
	    }
	}

	private static void searchAll(Criteria criteria, FieldFilter fieldFilter) throws Exception {
		String[] fields = fieldFilter.getField().split(FieldFilter.FIELD_SPLIT);
		String[] valClses = fieldFilter.getValueCls().split(FieldFilter.FIELD_SPLIT);
		Criterion criterion = null;
		for (int i=0; i<fields.length; i++) {
			Object value;
			try {
				value = Class.forName(valClses[i]).getConstructor(String.class).newInstance(fieldFilter.getValue());
			} catch (Exception e) {
				System.out.println("begug:不能获取实例值");
				continue;
			} 
			//不处理Booleano类型
			if (value instanceof Boolean) {
				continue;
			}
			if (value instanceof String) {
				criterion = or(criterion, Restrictions.like(fields[i], "%"+value+"%"));
			} else {
				criterion = or(criterion, Restrictions.like(fields[i], value));
			}
		}
		criteria.add(criterion);
	}
	
	private static Criterion or(Criterion crit1, Criterion crit2) {
        if (crit1 == null) {
            return crit2;
        }
        if (crit2 == null) {
           return crit1;
        }
        return Restrictions.or(crit1, crit2);
    }
}
